home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK2.toast / Development Kits (Disc 2) / QuickTime / Sample Code / QT QuickDraw 3D tracks / Code / 3DMF to Animated Movie / 3dMF2AnimatedMovie.c next >
Encoding:
C/C++ Source or Header  |  1997-02-26  |  9.8 KB  |  318 lines  |  [TEXT/CWIE]

  1. #include <Fonts.h>
  2. #include <Movies.h>
  3. #include <QD3D.h>
  4. #include <QD3DTransform.h>
  5.  
  6. OSErr addTweenEntryToSample(QTAtomContainer tweenSample, long tweenID, long tweenType,
  7.             void *tweenData, long tweenDataSize);
  8.  
  9. OSErr setTweenEntryStartOffset(QTAtomContainer tweenSample, long tweenID, TimeValue startOffset);
  10.  
  11. OSErr setTweenEntryDuration(QTAtomContainer tweenSample, long tweenID, TimeValue duration);
  12.  
  13. OSErr setTweenEntryInitialConditions(QTAtomContainer tweenSample, long tweenID,
  14.             void *initialData, long initialDataSize);
  15.  
  16. OSErr addTweenEntryToInputMapEntry(QTAtomContainer inputMap, long referenceIndex, long tweenID,
  17.                 long tweenType, char *name);
  18.  
  19. void main(void)
  20. {
  21.     OSErr err = noErr;
  22.     OSType types;
  23.     StandardFileReply reply;
  24.     Movie newMovie;
  25.     ThreeDeeDescriptionHandle sampleDescription = nil;
  26.     short fref;
  27.     AliasHandle alias = nil;
  28.     long eof;
  29.     Movie theMovie;
  30.     Track threeDeeTrack, tweenTrack;
  31.     Media threeDeeMedia, tweenMedia;
  32.     FSSpec movieFSS;
  33.     short movieResRef;
  34.     QTAtomContainer tweenSample;
  35.     TQ3Vector3D tweenScale;
  36.     TQ3Vector3D tweenTranslate;
  37.     TQ3RotateTransformData tweenRotate;
  38.     long referenceIndex1, referenceIndex2, referenceIndex3;
  39.     QTAtomContainer inputMap;
  40.  
  41.     InitGraf(&qd.thePort);
  42.     InitFonts();
  43.     InitWindows();
  44.     InitMenus();
  45.     TEInit();
  46.     InitDialogs(0L);
  47.     InitCursor();
  48.     MaxApplZone();
  49.  
  50.     EnterMovies();
  51.  
  52.     // ask user for a file
  53.     types = '3DMF';
  54.     StandardGetFilePreview(nil, 1, &types, &reply);
  55.     if (!reply.sfGood) return;
  56.  
  57.     // figure out the size of the file
  58.     FSpOpenDF(&reply.sfFile, fsRdPerm, &fref);
  59.     GetEOF(fref, &eof);
  60.     FSClose(fref);
  61.  
  62.     // make an alias to the file (QuickTime term: data reference)
  63.     NewAliasMinimal(&reply.sfFile, &alias);
  64.  
  65.     // make up a sample description for the 3d media
  66.     sampleDescription = (ThreeDeeDescriptionHandle)NewHandleClear(sizeof(ThreeDeeDescription));
  67.     if (err = MemError()) return;
  68.     (**sampleDescription).descSize = sizeof(ThreeDeeDescription);
  69.  
  70.     // create a movie file
  71.     FSMakeFSSpec(0, 0, "\p3D Animated Movie File", &movieFSS);
  72.     err = CreateMovieFile(&movieFSS, 'TVOD', -1, createMovieFileDeleteCurFile, &movieResRef, &theMovie);
  73.     if (err) return;
  74.  
  75.     // make up a 3d track, and media, very quickly
  76.     threeDeeTrack = NewMovieTrack(theMovie, 320 << 16, 240 << 16, 0);        // 320x240 pixels in size
  77.     threeDeeMedia = NewTrackMedia(threeDeeTrack, 'qd3d', 1000, (Handle)alias, rAliasType);        // make up a media that points to the 3dmf file
  78.  
  79.     // add the 3dmf file as a sample to the media (5 seconds long second long)
  80.     err = AddMediaSampleReference(threeDeeMedia, 0, eof, 5000, (SampleDescriptionHandle)sampleDescription,
  81.                 1, 0, nil);
  82.     if (err) return;
  83.  
  84.     // add the 3d media into the track
  85.     InsertMediaIntoTrack(threeDeeTrack, 0, 0, GetMediaDuration(threeDeeMedia), 1L << 16);
  86.  
  87.     // dispose unneeded things
  88.     DisposeHandle((Handle)alias);
  89.     DisposeHandle((Handle)sampleDescription);
  90.  
  91.     // make up a tween track, and media, very quickly
  92.     tweenTrack = NewMovieTrack(theMovie, 0, 0, 0);
  93.     tweenMedia = NewTrackMedia(tweenTrack, TweenMediaType, 1000, (Handle)nil, 0);        // make up a media that stores its data in the movie's file
  94.  
  95.     // make up an empty tween sample
  96.     err = QTNewAtomContainer(&tweenSample);
  97.     if (err) return;
  98.  
  99. #if 0
  100.     // add a tween entry to scale camera by factor of 1.4 in all dimensions
  101.     tweenScale.x = 
  102.     tweenScale.y = 
  103.     tweenScale.z = 1.4;
  104.     err = addTweenEntryToSample(tweenSample, 1, kTweenType3dScale, &tweenScale, sizeof(tweenScale));
  105.     if (err) return;
  106. #else
  107.     // add a tween entry to scale camera by factor from 0.1 to 2.0
  108.     tweenScale.x = 
  109.     tweenScale.y = 
  110.     tweenScale.z = 2.0;
  111.     err = addTweenEntryToSample(tweenSample, 1, kTweenType3dScale, &tweenScale, sizeof(tweenScale));
  112.     if (err) return;
  113.  
  114.     tweenScale.x = 
  115.     tweenScale.y = 
  116.     tweenScale.z = 0.1;
  117.     err = setTweenEntryInitialConditions(tweenSample, 1, &tweenScale, sizeof(tweenScale));
  118.     if (err) return;
  119. #endif
  120.  
  121. #if 0
  122.     // add tween entries to rotate camera by 30 degrees
  123.     tweenRotate.axis = kQ3AxisY;
  124.     tweenRotate.radians = 1.0;
  125.     err = addTweenEntryToSample(tweenSample, 2, kTweenType3dRotate, &tweenRotate, sizeof(tweenRotate));
  126.     if (err) return;
  127. #else
  128.     // add tween entries to rotate camera from +10.0 radians to +20.0 radians degrees
  129.     tweenRotate.axis = kQ3AxisY;
  130.     tweenRotate.radians = 20.0;
  131.     err = addTweenEntryToSample(tweenSample, 2, kTweenType3dRotate, &tweenRotate, sizeof(tweenRotate));
  132.     if (err) return;
  133.  
  134.     tweenRotate.axis = kQ3AxisY;
  135.     tweenRotate.radians = 10.0;
  136.     err = setTweenEntryInitialConditions(tweenSample, 2, &tweenRotate, sizeof(tweenRotate));
  137.     if (err) return;
  138.  
  139. #endif
  140.  
  141. #if 1
  142.     // add a tween entry to translate down
  143.     tweenTranslate.x = 0.0;
  144.     tweenTranslate.y = 3.0;
  145.     tweenTranslate.z = 0.0;
  146.     err = addTweenEntryToSample(tweenSample, 3, kTweenType3dTranslate, &tweenTranslate, sizeof(tweenTranslate));
  147.     if (err) return;
  148.  
  149.     tweenTranslate.x = 0.0;
  150.     tweenTranslate.y = -1.0;
  151.     tweenTranslate.z = 0.0;
  152.     err = setTweenEntryInitialConditions(tweenSample, 3, &tweenTranslate, sizeof(tweenTranslate));
  153.     if (err) return;
  154. #endif
  155.  
  156.     // make up a tween sample description
  157.     sampleDescription = (ThreeDeeDescriptionHandle)NewHandleClear(sizeof(SampleDescription));
  158.     if (err = MemError()) return;
  159.     (**sampleDescription).descSize = sizeof(SampleDescription);
  160.  
  161.     // add the tween sample to the tween media
  162.     err = BeginMediaEdits(tweenMedia);
  163.     if (err) return;
  164.  
  165.     err = AddMediaSample(tweenMedia, tweenSample, 0, GetHandleSize(tweenSample), 5000, (SampleDescriptionHandle)sampleDescription, 1, 0, nil);
  166.     if (err) return;
  167.  
  168.     err = EndMediaEdits(tweenMedia);
  169.     if (err) return;
  170.  
  171.     // add the tween media into the track
  172.     InsertMediaIntoTrack(tweenTrack, 0, 0, GetMediaDuration(tweenMedia), 1L << 16);
  173.  
  174.     // throw away a few things
  175.     QTDisposeAtomContainer(tweenSample);
  176.     DisposeHandle((Handle)sampleDescription);
  177.  
  178.     // create two links (references) between the 3d and tween tracks
  179.     err = AddTrackReference(threeDeeTrack, tweenTrack, kTrackModifierReference, &referenceIndex1);
  180.     if (err) return;
  181.  
  182.     err = AddTrackReference(threeDeeTrack, tweenTrack, kTrackModifierReference, &referenceIndex2);
  183.     if (err) return;
  184.  
  185.     err = AddTrackReference(threeDeeTrack, tweenTrack, kTrackModifierReference, &referenceIndex3);
  186.     if (err) return;
  187.  
  188.     // create an empty input map for the 3d track
  189.     err = QTNewAtomContainer(&inputMap);
  190.     if (err) return;
  191.  
  192.     err = addTweenEntryToInputMapEntry(inputMap, referenceIndex1, 1, kTrackModifierType3d4x4Matrix, nil);
  193.     if (err) return;
  194.  
  195.     err = addTweenEntryToInputMapEntry(inputMap, referenceIndex2, 2, kTrackModifierType3d4x4Matrix, nil);
  196.     if (err) return;
  197.  
  198.     err = addTweenEntryToInputMapEntry(inputMap, referenceIndex3, 3, kTrackModifierType3d4x4Matrix, "Joe");
  199.     if (err) return;
  200.  
  201.     // attach the input map to the 3d media handler
  202.     err = SetMediaInputMap(threeDeeMedia, inputMap);
  203.     if (err) return;
  204.  
  205.     // throw away the input map
  206.     QTDisposeAtomContainer(inputMap);
  207.  
  208.     // add the movie resource to the movie file
  209.     err = AddMovieResource(theMovie, movieResRef, nil, nil);
  210.     if (err) return;
  211.  
  212.     // close the movie file
  213.     CloseMovieFile(movieResRef);
  214.  
  215.     // toss that movie too (automatically tosses all tracks, media, etc).
  216.     DisposeMovie(theMovie);
  217. }
  218.  
  219. OSErr addTweenEntryToSample(QTAtomContainer tweenSample, long tweenID, long tweenType, 
  220.                                 void *tweenData, long tweenDataSize)
  221. {
  222.     OSErr err;
  223.     QTAtom tweenAtom;
  224.  
  225.     // create entry for this tween in the sample
  226.     err = QTInsertChild(tweenSample, kParentAtomIsContainer, kTweenEntry, tweenID, 0, 0, nil, &tweenAtom);
  227.     if (err) goto bail;
  228.  
  229.     // define the type of this tween entry
  230.     err = QTInsertChild(tweenSample, tweenAtom, kTweenType, 1, 0, sizeof(tweenType), &tweenType, nil);
  231.     if (err) goto bail;
  232.  
  233.     // define the data for this tween entry
  234.     err = QTInsertChild(tweenSample, tweenAtom, kTweenData, 1, 0, tweenDataSize, tweenData, nil);
  235.     if (err) goto bail;
  236.  
  237. bail:
  238.     return err;
  239. }
  240.  
  241. OSErr setTweenEntryStartOffset(QTAtomContainer tweenSample, long tweenID, TimeValue startOffset)
  242. {
  243.     QTAtom tweenAtom;
  244.  
  245.     // look up the tween entry
  246.     tweenAtom = QTFindChildByID(tweenSample, kParentAtomIsContainer, kTweenEntry, tweenID, nil);
  247.     if (!tweenAtom)
  248.         return paramErr;
  249.  
  250.     // add in the start offset
  251.     return QTInsertChild(tweenSample, tweenAtom, kTweenStartOffset, 1, 0, sizeof(startOffset), &startOffset, nil);
  252. }
  253.  
  254. OSErr setTweenEntryDuration(QTAtomContainer tweenSample, long tweenID, TimeValue duration)
  255. {
  256.     QTAtom tweenAtom;
  257.  
  258.     // look up the tween entry
  259.     tweenAtom = QTFindChildByID(tweenSample, kParentAtomIsContainer, kTweenEntry, tweenID, nil);
  260.     if (!tweenAtom)
  261.         return paramErr;
  262.  
  263.     // add in the start offset
  264.     return QTInsertChild(tweenSample, tweenAtom, kTweenDuration, 1, 0, sizeof(duration), &duration, nil);
  265. }
  266.  
  267. OSErr setTweenEntryInitialConditions(QTAtomContainer tweenSample, long tweenID,
  268.             void *initialData, long initialDataSize)
  269. {
  270.     QTAtom tweenAtom;
  271.  
  272.     // look up the tween entry
  273.     tweenAtom = QTFindChildByID(tweenSample, kParentAtomIsContainer, kTweenEntry, tweenID, nil);
  274.     if (!tweenAtom)
  275.         return paramErr;
  276.  
  277.     // add in the initial data offset
  278.     return QTInsertChild(tweenSample, tweenAtom, 'icnd', 1, 0, initialDataSize, initialData, nil);
  279. }
  280.  
  281. OSErr addTweenEntryToInputMapEntry(QTAtomContainer inputMap, long referenceIndex, long tweenID,
  282.                 long tweenType, char *name)
  283. {
  284.     OSErr err;
  285.     QTAtom inputAtom;
  286.  
  287.     // add a input entry to the input mape
  288.     err = QTInsertChild(inputMap, kParentAtomIsContainer, kTrackModifierInput, referenceIndex,
  289.                 0, 0, nil, &inputAtom);
  290.     if (err) goto bail;
  291.  
  292.     // set the type of the modifier input (for 3d, this is almost always kTrackModifierType3d4x4Matrix)
  293.     err = QTInsertChild(inputMap, inputAtom, kTrackModifierType, 1, 0, 
  294.                sizeof(tweenType), &tweenType, nil);
  295.     if (err) goto bail;
  296.  
  297.     // set the sub input id (the id of the tween entry)
  298.     err = QTInsertChild(inputMap, inputAtom, kInputMapSubInputID, 1, 0, 
  299.                sizeof(tweenID), &tweenID, nil);
  300.     if (err) goto bail;
  301.  
  302.     // define the name
  303.     if (name) {
  304.         long nameLen = 1;
  305.         Ptr p = name;
  306.  
  307.         while (*p++)
  308.             nameLen++;
  309.  
  310.         err = QTInsertChild(inputMap, inputAtom, kTrackModifierInputName, 1, 0, 
  311.                  nameLen, name, nil);
  312.         if (err) goto bail;
  313.     }
  314.  
  315. bail:
  316.     return err;
  317. }
  318.